﻿using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace CodeGenerate
{
    /// <summary>
    /// 代码协助通用类
    /// </summary>
    public class CodeCommon
    {
        static string datatypefile = AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\') + "\\DatatypeMap.cfg";

        #region 缩进间隔
        /// <summary>
        /// 缩进间隔
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public static string Space(int num)
        {
            StringBuilder str = new StringBuilder();
            for (int n = 0; n < num; n++)
            {
                str.Append("\t");
            }
            return str.ToString();
        }
        #endregion

        #region 转换 数据库字段类型 为 c#类型

        /// <summary>
        /// 转换【数据库字段类型】 =》为【c#类型】
        /// </summary>
        /// <param name="dbtype">数据库字段类型</param>
        /// <returns>c#类型</returns>		
        public static string DbTypeToCS(string dbtype)
        {
            string CSType = "string";
            if (File.Exists(datatypefile))
            {
                string val = DatatypeMap.GetValueFromCfg(datatypefile, "DbToCS", dbtype.ToLower().Trim());
                if (val == "")
                {
                    CSType = dbtype.ToLower().Trim();
                }
                else
                {
                    CSType = val;
                }
            }
            return CSType;

        }
        #endregion

        #region 是否c#中的值类型
        /// <summary>
        /// 是否c#中的值类型
        /// </summary>
        public static bool isValueType(string cstype)
        {
            bool isval = false;
            if (File.Exists(datatypefile))
            {
                string val = DatatypeMap.GetValueFromCfg(datatypefile, "ValueType", cstype.Trim());
                if (val == "true" || val == "是")
                {
                    isval = true;
                }
            }
            return isval;
        }
        #endregion

        #region （存储过程参数）得到 数据库字段类型 的 长度 (包括是否需要加)

        /// <summary>
        /// （存储过程参数）得到数据库字段类型的长度(包括是否需要加)
        /// </summary>
        /// <param name="dbtype">数据库字段类型</param>
        /// <returns></returns>
        public static string DbTypeLength(string dbtype, string datatype, string Length)
        {
            string strtype = "";
            switch (dbtype)
            {
                case "SQL2000":
                case "SQL2005":
                case "SQL2008":
                case "SQL2012":
                    strtype = DbTypeLengthSQL(dbtype, datatype, Length);
                    break;
                case "Oracle":
                    strtype = DbTypeLengthOra(datatype, Length);
                    break;
                case "MySQL":
                    strtype = DbTypeLengthMySQL(datatype, Length);
                    break;
                case "OleDb":
                    strtype = DbTypeLengthOleDb(datatype, Length);
                    break;
                case "SQLite":
                    strtype = DbTypeLengthSQLite(datatype, Length);
                    break;
            }
            return strtype;
        }

        #region DbTypeLength
        /// <summary>
        /// 得到某种类型字段应该的长度
        /// </summary>
        public static string GetDataTypeLenVal(string datatype, string Length)
        {
            string LenVal = "";
            switch (datatype.Trim())
            {
                case "int":
                    if (Length == "")
                    {
                        LenVal = "4";
                    }
                    else
                    {
                        LenVal = Length;
                    }
                    break;
                case "char":
                    {
                        if (Length.Trim() == "")
                        {
                            LenVal = "10";
                        }
                        else
                        {
                            LenVal = Length;
                        }
                    }
                    break;
                case "nchar":
                    {
                        LenVal = Length;
                        if (Length.Trim() == "")
                        {
                            LenVal = "10";
                        }
                        //else
                        //{
                        //    LenVal = (int.Parse(Length.Trim()) / 2).ToString();
                        //}   
                    }
                    break;
                case "varchar":
                case "nvarchar":
                case "varbinary":
                    {
                        LenVal = Length;
                        if (Length.Length == 0 || Length == "0" || Length == "-1")
                        {
                            LenVal = "MAX";
                        }

                        //else
                        //{
                        //    Length = (int.Parse(Length) / 2).ToString();
                        //}
                        //if (Length.Trim() == "")
                        //{
                        //    LenVal = "50";
                        //}
                        //else
                        //{
                        //    if (int.Parse(Length.Trim()) < 1)
                        //    {
                        //        LenVal = "";
                        //    }
                        //}
                    }
                    break;

                case "bit":
                    LenVal = "1";
                    break;
                case "float":
                case "numeric":
                case "decimal":
                case "money":
                case "smallmoney":
                case "binary":
                case "smallint":
                case "bigint":
                    LenVal = Length;
                    break;
                case "image":
                case "datetime":
                case "smalldatetime":
                case "ntext":
                case "text":
                    break;
                default:
                    LenVal = Length;
                    break;
            }
            return LenVal;
        }
        private static string DbTypeLengthSQL(string dbtype, string datatype, string Length)
        {
            string LenVal = GetDataTypeLenVal(datatype, Length);
            string lenstr = "";
            if (LenVal != "")
            {
                if (LenVal == "MAX")
                {
                    LenVal = "-1";
                }
                lenstr = CSToProcType(dbtype, datatype) + "," + LenVal;
            }
            else
            {
                lenstr = CSToProcType(dbtype, datatype);
            }
            return lenstr;
        }
        private static string DbTypeLengthOra(string datatype, string Length)
        {
            string len = "";
            switch (datatype.Trim().ToLower())
            {
                case "number":
                    if (Length == "")
                    {
                        len = "4";
                    }
                    else
                    {
                        len = Length;
                    }
                    break;
                case "varchar2":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "char":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "date":
                case "nchar":
                case "nvarchar2":
                case "long":
                case "long raw":
                case "bfile":
                case "blob":
                    break;
                default:
                    len = Length;
                    break;
            }

            if (len != "")
            {
                len = CSToProcType("Oracle", datatype) + "," + len;
            }
            else
            {
                len = CSToProcType("Oracle", datatype);
            }
            return len;
        }
        private static string DbTypeLengthMySQL(string datatype, string Length)
        {
            string len = "";
            switch (datatype.Trim().ToLower())
            {
                case "number":
                    if (Length == "")
                    {
                        len = "4";
                    }
                    else
                    {
                        len = Length;
                    }
                    break;
                case "varchar2":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "char":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "date":
                case "nchar":
                case "nvarchar2":
                case "long":
                case "long raw":
                case "bfile":
                case "blob":
                    //len = Length;
                    break;
                default:
                    len = Length;
                    break;
            }

            if (len != "")
            {
                len = CSToProcType("MySQL", datatype) + "," + len;
            }
            else
            {
                len = CSToProcType("MySQL", datatype);
            }
            return len;
        }
        private static string DbTypeLengthOleDb(string datatype, string Length)
        {
            string len = "";
            switch (datatype.Trim())
            {
                case "int":
                    if (Length == "")
                    {
                        len = "4";
                    }
                    else
                    {
                        len = Length;
                    }
                    break;
                case "varchar":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "char":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "bit":
                    len = "1";
                    break;
                case "float":
                case "numeric":
                case "decimal":
                case "money":
                case "smallmoney":
                case "binary":
                case "smallint":
                case "bigint":
                    len = Length;
                    break;
                case "image":
                case "datetime":
                case "smalldatetime":
                case "nchar":
                case "nvarchar":
                case "ntext":
                case "text":
                    break;
                default:
                    len = Length;
                    break;
            }

            if (len != "")
            {
                len = CSToProcType("OleDb", datatype) + "," + len;
            }
            else
            {
                len = CSToProcType("OleDb", datatype);
            }
            return len;
        }
        private static string DbTypeLengthSQLite(string datatype, string Length)
        {
            string len = "";
            switch (datatype.Trim())
            {
                case "int":
                case "integer":
                    if (Length == "")
                    {
                        len = "4";
                    }
                    else
                    {
                        len = Length;
                    }
                    break;
                case "varchar":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "char":
                    {
                        if (Length == "")
                        {
                            len = "50";
                        }
                        else
                        {
                            len = Length;
                        }
                    }
                    break;
                case "bit":
                    len = "1";
                    break;
                case "float":
                case "numeric":
                case "decimal":
                case "money":
                case "smallmoney":
                case "binary":
                case "smallint":
                case "bigint":
                case "blob":
                    len = Length;
                    break;
                case "image":
                case "datetime":
                case "smalldatetime":
                case "nchar":
                case "nvarchar":
                case "ntext":
                case "text":
                case "time":
                case "date":
                case "boolean":
                    break;
                default:
                    len = Length;
                    break;
            }

            if (len != "")
            {
                len = CSToProcType("SQLite", datatype) + "," + len;
            }
            else
            {
                len = CSToProcType("SQLite", datatype);
            }
            return len;
        }
        #endregion


        #endregion

        #region 转换 【c#类型 和 数据类型】 转为 【存储过程的参数】

        /// <summary>
        /// 转换c#类型和数据类型转为存储过程的参数类型
        /// </summary>
        /// <param name="dbtype">数据库字段类型</param>
        /// <returns>c#类型</returns>
        public static string CSToProcType(string DbType, string cstype)
        {
            string strtype = cstype;
            switch (DbType)
            {
                case "SQL2000":
                case "SQL2005":
                case "SQL2008":
                case "SQL2012":
                    strtype = CSToProcTypeSQL(cstype);
                    break;
                case "Oracle":
                    strtype = CSToProcTypeOra(cstype);
                    break;
                case "MySQL":
                    strtype = CSToProcTypeMySQL(cstype);
                    break;
                case "OleDb":
                    strtype = CSToProcTypeOleDb(cstype);
                    break;
                case "SQLite":
                    strtype = CSToProcTypeSQLite(cstype);
                    break;
            }
            return strtype;
        }

        #region CSToProcType

        private static string CSToProcTypeSQL(string cstype)
        {
            string CSType = cstype;
            if (File.Exists(datatypefile))
            {
                //datatype = new Maticsoft.Utility.INIFile(datatypefile);
                //string val = datatype.IniReadValue("ToSQLProc", cstype.ToLower().Trim());
                string val = DatatypeMap.GetValueFromCfg(datatypefile, "SQLDbType", cstype.ToLower().Trim());
                if (val == "")
                {
                    CSType = cstype.ToLower().Trim();
                }
                else
                {
                    CSType = val;
                }
            }
            return CSType;
        }

        private static string CSToProcTypeOra(string cstype)
        {
            string CSType = cstype;
            if (File.Exists(datatypefile))
            {
                //datatype = new Maticsoft.Utility.INIFile(datatypefile);
                //string val = datatype.IniReadValue("ToOraProc", cstype.ToLower().Trim());
                string val = DatatypeMap.GetValueFromCfg(datatypefile, "OraDbType", cstype.ToLower().Trim());
                if (val == "")
                {
                    CSType = cstype.ToLower().Trim();
                }
                else
                {
                    CSType = val;
                }
            }
            return CSType;
        }

        private static string CSToProcTypeMySQL(string cstype)
        {
            string CSType = cstype;
            if (File.Exists(datatypefile))
            {
                //datatype = new Maticsoft.Utility.INIFile(datatypefile);
                //string val = datatype.IniReadValue("ToMySQLProc", cstype.ToLower().Trim());
                string val = DatatypeMap.GetValueFromCfg(datatypefile, "MySQLDbType", cstype.ToLower().Trim());
                if (val == "")
                {
                    CSType = cstype.ToLower().Trim();
                }
                else
                {
                    CSType = val;
                }
            }
            return CSType;
        }

        private static string CSToProcTypeOleDb(string cstype)
        {
            string CSType = cstype;
            if (File.Exists(datatypefile))
            {
                //datatype = new Maticsoft.Utility.INIFile(datatypefile);
                //string val = datatype.IniReadValue("ToOleDbProc", cstype.ToLower().Trim());
                string val = DatatypeMap.GetValueFromCfg(datatypefile, "OleDbDbType", cstype.ToLower().Trim());
                if (val == "")
                {
                    CSType = cstype.ToLower().Trim();
                }
                else
                {
                    CSType = val;
                }
            }
            return CSType;
        }

        private static string CSToProcTypeSQLite(string cstype)
        {
            string CSType = cstype;
            if (File.Exists(datatypefile))
            {
                //datatype = new Maticsoft.Utility.INIFile(datatypefile);
                //string val = datatype.IniReadValue("ToSQLiteProc", cstype.ToLower().Trim());
                string val = DatatypeMap.GetValueFromCfg(datatypefile, "SQLiteType", cstype.ToLower().Trim());
                if (val == "")
                {
                    CSType = cstype.ToLower().Trim();
                }
                else
                {
                    CSType = val;
                }
            }
            return CSType;
        }

        #endregion

        #endregion


        /// <summary>
        /// 转换为驼峰
        /// </summary>
        /// <param name="strItem"></param>
        /// <returns></returns>
        public static string Convert2TF(string strItem)
        {
            string[] strItems = strItem.Split('_');
            string strItemTarget = strItems[0];
            strItemTarget = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(strItemTarget);
            for (int j = 1; j < strItems.Length; j++)
            {
                string temp = strItems[j].ToString();
                string temp1 = temp[0].ToString().ToUpper();
                string temp2 = "";
                temp2 = temp1 + temp.Remove(0, 1);
                temp2 = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(temp2);
                strItemTarget += temp2;
            }

            return strItemTarget;
        }

        /// <summary>
        /// 转化为下划线
        /// </summary>
        /// <param name="strItem"></param>
        /// <returns></returns>
        public static string Convert2XHX(string strItem)
        {
            string strItemTarget = "";
            for (int j = 0; j < strItem.Length; j++)
            {
                string temp = strItem[j].ToString();
                if (Regex.IsMatch(temp, "[A-Z]"))
                {
                    temp = "_" + temp.ToLower();
                }
                strItemTarget += temp;
            }
            return strItemTarget.ToLower();
        }
    }
}